'''
利用斗鱼弹幕 api
尝试抓取斗鱼tv指定房间的弹幕
'''

import multiprocessing
import socket
import time
import re
import signal

# 构造socket连接，和斗鱼api服务器相连接
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = socket.gethostbyname("openbarrage.douyutv.com")
port = 8601
client.connect((host, port))

# 弹幕查询正则表达式
danmu_re = re.compile(b'txt@=(.+?)/cid@')
username_re = re.compile(b'nn@=(.+?)/txt@')


#格式化消息方法
def send_req_msg(msgstr,client):
    '''构造并发送符合斗鱼api的请求'''

    msg = msgstr.encode('utf-8')
    print(msg)
    #消息内容的字节数+消息的头部信息的字节数 == 消息的长度
    data_length = len(msg) + 8
    print(data_length)
    code = 689
    # 构造协议头
    msgHead = int.to_bytes(data_length, 4, 'little') \
              + int.to_bytes(data_length, 4, 'little') + \
        int.to_bytes(code, 4, 'little')

    client.send(msgHead)
    client.send(msg)




def DM_start(roomid,client):
    # 构造登录授权请求
    msg = 'type@=loginreq/roomid@={}/\0'.format(roomid)
    send_req_msg(msg,client)
    # 构造获取弹幕消息请求
    msg_more = 'type@=joingroup/rid@={}/gid@=-9999/\0'.format(roomid)
    send_req_msg(msg_more,client)

    while True:
        # 服务端返回的数据

        data = client.recv(1024)
        # print(data)
        # 通过re模块找发送弹幕的用户名和内容
        danmu_username = username_re.findall(data)
        danmu_content = danmu_re.findall(data)


        for i in range(0, len(danmu_content)):
            try:
                # 输出信息
                print('[{}]:{}'.format(danmu_username[i].decode(
                        'utf8'), danmu_content[i].decode(encoding='utf8')))
            except:
                continue


def keeplive(client):
    '''
    保持心跳，45秒心跳请求一次
     '''
    while True:
        msg = 'type@=keeplive/tick@={}/\0'.format(int(time.time()))
        send_req_msg(msg,client)
        print('发送心跳包')
        time.sleep(45)

# 先更他连接  登录  入组  45s 发送一个心跳包



if __name__ == '__main__':
    #room_id = input('请输入房间ID： ')

    # lpl
    room_id = '290935'
    # 开启signal捕捉

    # 开启弹幕和心跳进程
    p1 = multiprocessing.Process(target=DM_start, args=(room_id,client))
    p2 = multiprocessing.Process(target=keeplive,args=(client,))
    p1.start()
    p2.start()